// 动画层 线 相关部分
import { transform, getTransform } from 'ol/proj' // 坐标转换
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import Overlay from 'ol/Overlay'
import Icon from 'ol/style/Icon'
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style,
  Text
} from 'ol/style'

export default {
  data () {
    return {
      // oMap: null, // 地图对象;    简写对照 overlay[ovl], arrow[arw], sprite[spt], Endpoint[ept]
      spriteGID: null // 精灵组ID，需求，小车需要根据dclass选择，但是数据无法与路线id匹配-获取不到，所以独立出来
    }
  },
  watch: {
    // watch
  },
  mounted () {
  },
  methods: {
    /**
     * @description 绘制动画精灵;注意精灵的id是提供的批次id--内部自己添加spt_前缀
     * @param {Object} oSource 获取的资源数据
     * @param {String} sRCS 表示地图使用的坐标系,如：EPSG:3857
     */
    drawAnimSprite (oSource, sRCS = this.sMapRCS) {
      const oBubble = oSource.properties.Bubble || null
      const dClass = oSource.properties.dClass || oSource.properties.dType // 默认为id - 标识关联的一组
      const sExt = oSource.properties.ext || 'SPRITE' // 创建Feature的类型
      const spriteCoord = oSource.geometry.coordinates // 获得线的顶点信息
      const sState = oSource.properties.state // 精灵状态
      const geometry = new Point(spriteCoord)
      if (sRCS !== this.sSRS) {
        geometry.applyTransform(getTransform(this.sSRS, sRCS)) // sSrS资源格式，sRCS数据格式
      }
      // 创建精灵Feature
      const spriteFeature = new Feature({ // ol.Feature
        geometry: geometry, // ol.geom.lineSting
        type: sExt, // add for select
        dType: 'sprite', // 表示当前feature为精灵
        state: sState, // 标识当前状态 normal，warn，error
        dClass: dClass, // 数据分类标志，选择时--通过此字段关联相同类的数据（同时选择路线和其上车辆）
        Bubble: oBubble
      })
      spriteFeature.setId('spt_' + oSource.properties.id)
      spriteFeature.setStyle(this.getAnimStyle(oSource.properties))
      this.animSource.addFeature(spriteFeature) // 向地图中添加精灵
      // 显示路径基本信息
      this.showSpriteBaseInfo(spriteFeature)
    },
    /**
     * @description 显示路线的基本信息（疏散人数等）
     * @param {object} oSpriteFeature 线的基本信息
     * 此方法和linePart中的showLineBaseInfo方法功能一致，仅有部分需要调整
     */
    showSpriteBaseInfo (oSpriteFeature) {
      const geometry = oSpriteFeature.getGeometry()
      const iType = geometry.getType().toLowerCase() // 几何类型
      console.log(iType)
      if (iType !== 'point') return // 目前精灵只是 点类型
      const aSpriteCP = geometry.getCoordinates() // 获取点坐标（featrue从当前显示获取，不用坐标转换）
      // 获取气泡中的信息
      const sRoadInfo = oSpriteFeature.get('Bubble')
      let sBaseInfo = null
      if (sRoadInfo) { // 如果有气泡信息，获取基本信息
        sBaseInfo = sRoadInfo.summary // 获取概览信息
      }
      // console.log(oSpriteFeature, sRoadInfo, sBaseInfo)
      if (sBaseInfo) { // 如果有概信息，展示到精灵
        const sID = oSpriteFeature.getId()
        // 创建overlay
        const infoDIV = document.createElement('div')
        infoDIV.className = 'anim-baseinfo'
        infoDIV.id = sID
        infoDIV.innerHTML = sBaseInfo
        // 将气泡div添加到HTML--动画层
        const animContainer = document.getElementById('animate-container')
        animContainer.appendChild(infoDIV)
        // 创建信息框
        const overlay = new Overlay({
          id: 'ovl_' + sID,
          element: infoDIV,
          positioning: 'top-center',
          stopEvent: false,
          autoPan: true,
          autoPanAnimation: {
            duration: 250
          }
        })
        overlay.setPosition(aSpriteCP)
        this.oMap.addOverlay(overlay)
        // 添加到地图上展示
      }
    },
    /**
     * @description sprite移动方法;moveFeature
     * @param {String} gID 精灵的唯一标识；此id为批次或组id--精灵需要加spt_前缀-->spriteID
     * @param {Array} aNewCoord 提供新的坐标（默认提EPSG:4326 经纬度坐标）
     * @param {String} sCoordSRS 提供坐标使用的空间参考坐标（Spatial Reference System)
     */
    moveSprite (gID, aNewCoord, sCoordSRS = 'EPSG:4326') {
      if (!this.animSource) return // 没有精灵层数据
      const spriteID = 'spt_' + gID
      const oSpriteFeature = this.animSource.getFeatureById(spriteID)
      if (!oSpriteFeature) return // 没有找到指定的精灵对象
      let aPosition = null
      // if (sCoordSRS !== this.sMapRCS) {
      if (sCoordSRS !== 'EPSG:3857') {
        // aPosition = transform(aNewCoord, sCoordSRS, this.sMapRCS)
        aPosition = transform(aNewCoord, sCoordSRS, 'EPSG:3857')
      } else {
        aPosition = aNewCoord
      }
      const oGeomSprite = oSpriteFeature.getGeometry()
      const iType = oGeomSprite.getType().toLowerCase() // 几何类型
      console.log(iType)
      if (iType !== 'point') return // 目前精灵被认为是point
      oGeomSprite.setCoordinates(aPosition)
      const overlaySprite = this.oMap.getOverlayById('ovl_' + spriteID)
      if (overlaySprite) {
        overlaySprite.setPosition(aPosition)
      }
    },
    /**
     * @description 根据ID选择精灵对象
     * @param {string} sGID 唯一标识--如:选择的路径id  内部添加‘spt_前缀’
     * @return {object} 气泡信息--如果有的话，否则null
     */
    selectSpriteByID (sGID) {
      const spriteID = 'spt_' + sGID
      if (this.animSelected && this.animSelected.id === spriteID) {
        return // 当前所选Feature的id与之前选择的id一致；退出不做处理（两次选择相同退出）
      }
      if (this.animSelected && this.animSelected.id !== spriteID) { // 如果之前有选择且与当前不同
        // console.log('cleanSelFeatureByID')
        this.cleanSelFeatureByID()
        // this.animSelected = null // 清理方法中释放
      }
      const spriteFeatrue = this.animSource.getFeatureById(spriteID)
      // 找到了所选精灵feature后进行处理;
      if (spriteFeatrue) {
        const iType = spriteFeatrue.getGeometry().getType().toLowerCase()
        if (iType !== 'point') return
        const oldStyle = spriteFeatrue.getStyle()
        this.animSelected = { id: spriteID, style: oldStyle } // 保存精灵原有样式
        const spriteImgSrc = spriteFeatrue.getStyle().getImage().getSrc()
        const rotate = spriteFeatrue.getStyle().getImage().getRotation()
        const aTmp = spriteImgSrc.split('.')
        if (aTmp.length !== 2) return // 返回的图潘地址中不知包含一个.
        const spriteImg = aTmp[0] + '_hl.' + aTmp[1] // 将图片设置为高亮(Highlight)图片
        const newSpriteStyle = new Style({
          image: new Icon({
            // color: this.sMarkColor,
            crossOrigin: 'anonymous',
            src: spriteImg,
            // rotateWithView: true,
            rotation: rotate // 从原有样式获取旋转弧度, 不用-rotation
          })
        })
        spriteFeatrue.setStyle(newSpriteStyle)
        // 信息框处理
        this.addClassStyle(spriteID, 'selectedDiv')
        // 返回气泡数据
        return spriteFeatrue.get('Bubble')
      }
    },

    /**
     * @description 清除当前所选精灵样式，还原之前的样式
     * @param {string} sSpritID 唯一标识--如:选择的精灵id，此id自带spt_前缀
     * @return {object} 气泡信息--如果有的话，否则null
     */
    cleanSelSpriteByID (sSpritID) {
      if (!sSpritID) return
      const spriteFeatrue = this.animSource.getFeatureById(sSpritID)
      if (spriteFeatrue) { // 找到了所选feature后进行处理;
        const oldStyle = this.animSelected.style
        if (oldStyle) {
          spriteFeatrue.setStyle(oldStyle) // 回复Feature原来的样式
        } else {
          // 将图片改成不带_hl的 img
          const spriteImgSrc = spriteFeatrue.getStyle().getImage().getSrc()
          const rotate = spriteFeatrue.getStyle().getImage().getRotation()
          // const anchor = spriteFeatrue.getStyle().getImage().getAnchor()
          const aTmp = spriteImgSrc.split('.')
          if (aTmp.length !== 2) return // 返回的图潘地址中不知包含一个. (/)
          const spriteImg = aTmp[0].substr(0, aTmp[0].length - 3) + '.' + aTmp[1] // 去掉串中的‘_hl’(Highlight)
          console.log(spriteImg)
          const oldSpriteStyle = new Style({
            image: new Icon({
              // color: '#FFF', // 修改图标img不改颜色
              crossOrigin: 'anonymous',
              src: spriteImg,
              // anchor: anchor,
              // rotateWithView: true,
              rotation: rotate // 从原有样式获取旋转弧度, 不用-rotation
            })
          })
          spriteFeatrue.setStyle(oldSpriteStyle)
        }
        // 处理其他关联对象
        this.cleanClassStylr(sSpritID, 'selectedDiv')
        this.animSelected = null
      }
    },

    /**
     * @description 改变feature的图标样式-高亮与普通切换
     * @param {Objecet} oFeature 要修改样式的feature
     * @return {object} 气泡信息--如果有的话，否则null
     */
    toggleFeatureIcon (oFeature) {
      if (oFeature) {
        const iType = oFeature.getGeometry().getType().toLowerCase()
        if (iType !== 'point') return
        // const oldStyle = oFeature.getStyle()
        // this.animSelected = { id: spriteID, style: oldStyle } // 保存精灵原有样式
        console.log(oFeature)
        console.log(oFeature.getStyle())

        const img = oFeature.getStyle().getImage()
        console.log(img instanceof Icon)
        if (!(img instanceof Icon)) return
        const spriteImgSrc = oFeature.getStyle().getImage().getSrc()
        const rotate = oFeature.getStyle().getImage().getRotation()
        const aTmp = spriteImgSrc.split('.')
        if (aTmp.length !== 2) return // 返回的图片地址中不只包含一个.
        // 读取aTmp元素0；参看是否包含'_hl'
        const sFlag = aTmp[0].substring(aTmp[0].length - 3)
        console.log(sFlag)
        let spriteImg
        if (sFlag === '_hl') {
          spriteImg = aTmp[0].substr(0, aTmp[0].length - 3) + '.' + aTmp[1] // 去掉串中的‘_hl’(Highlight)
        } else {
          spriteImg = aTmp[0] + '_hl.' + aTmp[1] // 将图片设置为高亮(Highlight)图片
        }
        const newSpriteStyle = new Style({
          image: new Icon({
            // color: this.sMarkColor,
            crossOrigin: 'anonymous',
            src: spriteImg,
            // rotateWithView: true,
            rotation: rotate // 从原有样式获取旋转弧度, 不用-rotation
          })
        })
        oFeature.setStyle(newSpriteStyle)
        // 信息框处理
        const sSpritID = oFeature.getId()
        console.log(sSpritID)
        if (sFlag === '_hl') {
          this.cleanClassStylr(sSpritID, 'selectedDiv')
        } else {
          this.addClassStyle(sSpritID, 'selectedDiv')
        }
        // 返回气泡数据
        return oFeature.get('Bubble')
      }
    },
    /**
     * @description 选择精灵根据组id
     * @param {string} sGroupID 唯一标识-组id 如：dclass
     * @return null
     */
    selectSpriteByGID (sGroupID) {
      if (this.spriteGID && this.spriteGID === sGroupID) {
        return // 组id相同，不做处理
      }
      if (this.spriteGID && this.spriteGID !== sGroupID) {
        this.cleanSelSpriteByGID() // 使用this.spriteGID清除所有样式
      }
      this.spriteGID = sGroupID
      const spriteFeatrues = this.animSource.getFeatures()
      const iNum = spriteFeatrues.length
      for (let i = 0; i < iNum; i++) {
        const oFeature = spriteFeatrues[i]
        if (oFeature.get('dClass') === sGroupID) {
          this.toggleFeatureIcon(oFeature)
        }
      }
    },
    // 精灵组样式清除
    cleanSelSpriteByGID (sGroupID) {
      sGroupID = sGroupID || this.spriteGID
      if (!sGroupID) return
      const spriteFeatrues = this.animSource.getFeatures()
      const iNum = spriteFeatrues.length
      for (let i = 0; i < iNum; i++) {
        const oFeature = spriteFeatrues[i]
        if (oFeature.get('dClass') === sGroupID) {
          this.toggleFeatureIcon(oFeature)
        }
      }
      this.spriteGID = null
    },

    /**
     * @description 更新指定Feature的气泡信息
     * @param {String} gID 要更新气泡的featrue的id
     * @param {Object} oBubble 要更新的气泡对象 {新气泡中的数据，存在更新，不存在添加}
     * @param {String} sPrefix 前缀
     */
    updateSpriteBubbleByID (gID, oBubble, sPrefix = 'spt_') {
      const spriteID = sPrefix + gID
      this.updateBubbleByID(spriteID, oBubble)
    },
    /**
     * @description 清除指定精灵的气泡信息
     * @param {String} gID 要更新气泡的featrue的id - 需要添加前缀
     * @param {Object} oBubble 要清除的气泡对象 {气泡中存在的key，删除对应的气泡中属性}}
     * @param {String} sPrefix 前缀
     */
    cleanSpriteBubbleByID (gID, oBubble, sPrefix = 'spt_') {
      const spriteID = sPrefix + gID
      this.cleanBubbleByID(spriteID, oBubble)
    },
    /**
     * @description 删除指定精灵的气泡
     * @param {string} gID 要素ID
     * @param {String} sPrefix 前缀
     */
    cleanSpritOverlayByID (gID, sPrefix = 'spt_') {
      const sID = 'ovl_' + sPrefix + gID // 路径的气泡id是 要素id前加上 'ovl_'
      this.cleanOverlayByID(sID)
    },
    /**
     * @description 创建指定的精灵气泡
     * @param {string} gID 要素ID
     * @param {String} sPrefix 前缀
     */
    createSpritOverlayByID (gID, sPrefix = 'spt_') {
      const spriteID = sPrefix + gID
      this.createOverlayByID(spriteID)
    },
    /**
     * @description 修改精灵简单气泡层
     * @param {string} gID 要素ID
     * @param {string} sBaseInfo 修改的内容
     * @param {String} sPrefix 前缀
     */
    updateSpriteBaseInfo (gID, sBaseInfo, sPrefix = 'spt_') {
      const sID = sPrefix + gID
      const popDiv = document.getElementById(sID)
      if (popDiv) {
        popDiv.innerHTML = sBaseInfo
      }
    },
    /**
     * @description 改变精灵icon图标
     * @param {string} gID 要素ID
     * @param {String} sIconName 要更换的Icon新图片文件名,如果不带后缀使用png后缀
     * @param {String} sPrefix 前缀
     */
    changeSpriteIcon (gID, sIconName, sPrefix = 'spt_') {
      console.log(sIconName)
      const sSpritID = sPrefix + gID
      const spriteFeatrue = this.animSource.getFeatureById(sSpritID)
      if (spriteFeatrue) { // 找到了所选feature后进行处理;
        const iType = spriteFeatrue.getGeometry().getType().toLowerCase()
        if (iType !== 'point') return
        // const oldStyle = spriteFeatrue.getStyle()
        const rotate = spriteFeatrue.getStyle().getImage().getRotation()
        let spriteImg = null

        const spriteImgSrc = spriteFeatrue.getStyle().getImage().getSrc()
        const aPathName = this.getFilePathName(spriteImgSrc)
        if (aPathName.length !== 2) return // 返回的图片地址中不知包含一个点
        if (sIconName.split('.').length > 1) { // 存在后缀
          spriteImg = aPathName[0] + '/' + sIconName
        } else {
          spriteImg = aPathName[0] + '/' + sIconName + '.png'
        }
        console.log(spriteImg)
        const newSpriteStyle = new Style({
          image: new Icon({
            // color: this.sMarkColor,
            crossOrigin: 'anonymous',
            src: spriteImg,
            // rotateWithView: true,
            rotation: rotate // 从原有样式获取旋转弧度, 不用-rotation
          })
        })
        // 设置新的icon样式
        spriteFeatrue.setStyle(newSpriteStyle)
      }
    },
    /**
     * @description 改变精灵state属性
     * @param {string} gID 要素ID
     * @param {String} sIconName 要更换的Icon新图片文件名,如果不带后缀使用png后缀
     * @param {String} sPrefix 前缀
     */
    changeSpriteState (gID, sState, sPrefix = 'spt_') {
      const sSpritID = sPrefix + gID
      const spriteFeatrue = this.animSource.getFeatureById(sSpritID)
      if (spriteFeatrue) { // 找到了所选feature后进行处理;
        spriteFeatrue.set('state', sState)
      }
      console.log(spriteFeatrue)
    },
    /** 获取精灵状态 */
    getSpriteState (gID, sPrefix = 'spt_') {
      const sSpritID = sPrefix + gID
      const spriteFeatrue = this.animSource.getFeatureById(sSpritID)
      if (spriteFeatrue) { // 找到了所选feature后进行处理;
        return spriteFeatrue.get('state')
      }
    },
    /**
     * @description 获取精灵的Icon图片Src路径字符串
     * @param {string} gID 要素ID
     * @param {String} sPrefix 前缀
     * @returns {String} 图片src； 包括路径和文件名称
     */
    getSpriteImg (gID, sPrefix = 'spt_') {
      const spriteID = sPrefix + gID
      console.log(spriteID)
      const spriteFeatrue = this.animSource.getFeatureById(spriteID)
      if (spriteFeatrue) {
        const spriteImgSrc = spriteFeatrue.getStyle().getImage().getSrc()
        return spriteImgSrc
      }
    },
    getSpriteLineID (gID, sPrefix = 'spt_') {
      const spriteID = sPrefix + gID
      console.log(spriteID)
      const spriteFeatrue = this.animSource.getFeatureById(spriteID)
      console.log(spriteFeatrue)
      if (spriteFeatrue) {
        return spriteFeatrue.get('dClass')
      }
    },

    /**
     * @description 更新精灵位置
     * @param {Object} oData 位置数据{'account': '86912312', 'lng': '116.271', 'lat': '39.881', 'sendTime': '2021-03-15 16:36:37'}
     */
    updateSpriteLocation (oData) {
      if (!oData || oData === {}) return
      const sID = 'spt_' + oData.account
      const fLng = parseFloat(oData.lng)
      const fLat = parseFloat(oData.lat)
      const sTime = oData.sendTime
      console.log(sID, fLng, fLat, sTime)
      // 根据id获取sprite对象
      // const spriteFeature = this.animSource.getFeatureById(sID)
      // if (!spriteFeature) return
      // moveSprite (gID, aNewCoord, sCoordSRS = 'EPSG:4326')
      this.moveSprite(oData.account, [fLng, fLat], 'EPSG:4326')
    },
    /**
     * @description 更新POI位置
     * @param {Object} oData 位置数据{'account': '86912312', 'lng': '116.271', 'lat': '39.881', 'sendTime': '2021-03-15 16:36:37'}
     */
    updatePOILocation (oData) {
      console.log(oData)
      if (!oData || oData === {}) return
      const sID = oData.account // 不是精灵对象，不用加‘spt_’
      const fLng = parseFloat(oData.lng)
      const fLat = parseFloat(oData.lat)
      const sTime = oData.sendTime
      console.log(sID, fLng, fLat, sTime)
      // 根据id获取sprite对象
      // const spriteFeature = this.animSource.getFeatureById(sID)
      // if (!spriteFeature) return
      // moveSprite (gID, aNewCoord, sCoordSRS = 'EPSG:4326')
      this.movePOI(oData.account, [fLng, fLat], 'EPSG:4326')
    },
    // 移动POI
    movePOI (gID, aNewCoord, sCoordSRS = 'EPSG:4326') {
      const oPOI = this.$parent.getTargetByID(gID)
      if (!oPOI) return // 没有找到指定的精灵对象
      let aPosition = null
      if (sCoordSRS !== this.$parent.conf.RCS) {
        aPosition = transform(aNewCoord, sCoordSRS, this.$parent.conf.RCS) // this.sMapRCS
      } else {
        aPosition = aNewCoord
      }
      const oGeomSprite = oPOI.getGeometry()
      const iType = oGeomSprite.getType().toLowerCase() // 几何类型
      // console.log(iType)
      if (iType !== 'point') return // 目前精灵被认为是point
      oGeomSprite.setCoordinates(aPosition)
      const overlayPoi = this.$parent.imap.getOverlayById('pop' + gID)
      if (overlayPoi) {
        overlayPoi.setPosition(aPosition)
      }
    }
  }
}
